package org.example.dbcompare.service.config;

import cn.hutool.db.ds.simple.SimpleDataSource;
import org.example.dbcompare.model.ConnectionInfo;
import org.yaml.snakeyaml.Yaml;

import java.io.InputStream;
import java.util.Map;
import java.util.logging.Logger;

/**
 * 读取yaml文件获取数据库链接信息
 * @author wuyong
 * @date 2025/10/26
 */
public class ConnectionInfoManager {
    private static final Logger logger = Logger.getLogger(ConnectionInfoManager.class.getName());
    private static final String UAT_CONFIG_FILE_PATH = "saas-uat-rds-config.yml";
    private static final String PROD_CONFIG_FILE_PATH = "saas-prd-rds-config.yml";
    private static final String LOCAL_CONFIG_FILE_PATH = "saas-local-rds-config.yml";
    public static SimpleDataSource  getDataSource(String envName, String tenantId){
        ConnectionInfo connectionInfo = get(envName, tenantId);
        return new SimpleDataSource(
                connectionInfo.getUrl(),
                connectionInfo.getUsername(),
                connectionInfo.getPassword()
        );
    }
    /**
     * 根据环境名称和租户ID获取数据库连接信息
     * @param envName 环境名称 (uat/prod)
     * @param tenantId 租户ID
     * @return ConnectionInfo 数据库连接信息
     * @throws RuntimeException 当配置文件不存在或解析失败时抛出异常
     */
    public static ConnectionInfo get(String envName, String tenantId) {
        if (envName == null || envName.trim().isEmpty()) {
            throw new IllegalArgumentException("环境名称不能为空");
        }
        if (tenantId == null || tenantId.trim().isEmpty()) {
            throw new IllegalArgumentException("租户ID不能为空");
        }
        
        try {
            // 根据环境名称选择配置文件
            String configFilePath = getConfigFilePath(envName);
            logger.info("正在读取配置文件: " + configFilePath + ", 租户ID: " + tenantId);
            
            // 读取YAML文件
            Map<String, Object> config = loadYamlConfig(configFilePath);
            
            // 解析配置并获取指定租户的连接信息
            ConnectionInfo connectionInfo = parseConnectionInfo(config, tenantId);
            
            if (connectionInfo == null) {
                throw new RuntimeException("未找到租户 " + tenantId + " 在环境 " + envName + " 中的数据库连接配置");
            }
            
            logger.info("成功获取租户 " + tenantId + " 的数据库连接信息");
            return connectionInfo;
            
        } catch (Exception e) {
            logger.severe("获取数据库连接信息失败: " + e.getMessage());
            throw new RuntimeException("获取数据库连接信息失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 根据环境名称获取配置文件路径
     */
    private static String getConfigFilePath(String envName) {
        switch (envName.toLowerCase()) {
            case "local":
                return LOCAL_CONFIG_FILE_PATH;
            case "uat":
                return UAT_CONFIG_FILE_PATH;
            case "prod":
            case "production":
                return PROD_CONFIG_FILE_PATH;
            default:
                throw new IllegalArgumentException("不支持的环境名称: " + envName + ", 支持的环境: uat, prod");
        }
    }
    
    /**
     * 加载YAML配置文件
     */
    @SuppressWarnings("unchecked")
    private static Map<String, Object> loadYamlConfig(String configFilePath) {
        try (InputStream inputStream = ConnectionInfoManager.class.getClassLoader().getResourceAsStream(configFilePath)) {
            if (inputStream == null) {
                throw new RuntimeException("配置文件不存在: " + configFilePath);
            }
            
            Yaml yaml = new Yaml();
            return yaml.loadAs(inputStream, Map.class);
        } catch (Exception e) {
            throw new RuntimeException("读取配置文件失败: " + configFilePath, e);
        }
    }
    
    /**
     * 从配置中解析指定租户的连接信息
     */
    @SuppressWarnings("unchecked")
    private static ConnectionInfo parseConnectionInfo(Map<String, Object> config, String tenantId) {
        try {
            // 导航到 datasource 配置
            Map<String, Object> spring = (Map<String, Object>) config.get("spring");
            if (spring == null) {
                throw new RuntimeException("配置文件中缺少 spring 节点");
            }
            
            Map<String, Object> datasource = (Map<String, Object>) spring.get("datasource");
            if (datasource == null) {
                throw new RuntimeException("配置文件中缺少 spring.datasource 节点");
            }
            
            Map<String, Object> dynamic = (Map<String, Object>) datasource.get("dynamic");
            if (dynamic == null) {
                throw new RuntimeException("配置文件中缺少 spring.datasource.dynamic 节点");
            }
            
            Map<String, Object> datasources = (Map<String, Object>) dynamic.get("datasource");
            if (datasources == null) {
                throw new RuntimeException("配置文件中缺少 spring.datasource.dynamic.datasource 节点");
            }
            
            // 获取指定租户的配置
            Map<String, Object> tenantConfig = (Map<String, Object>) datasources.get(tenantId);
            if (tenantConfig == null) {
                logger.warning("未找到租户 " + tenantId + " 的配置，可用租户: " + datasources.keySet());
                return null;
            }
            
            // 提取连接信息
            String url = (String) tenantConfig.get("url");
            String username = (String) tenantConfig.get("username");
            String password = (String) tenantConfig.get("password");
            
            if (url == null || username == null || password == null) {
                throw new RuntimeException("租户 " + tenantId + " 的配置不完整，缺少 url、username 或 password");
            }
            
            return ConnectionInfo.builder()
                    .url(url)
                    .username(username)
                    .password(password)
                    .build();
                    
        } catch (ClassCastException e) {
            throw new RuntimeException("配置文件格式错误，无法解析租户 " + tenantId + " 的配置", e);
        }
    }
}
